package com.mybatisplus.common;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.function.ConverterFileName;

import java.util.Collections;
import java.util.List;

public class ConfigUtils {
    /**
     * 获得全局配置
     * 全局配置提供了对代码生成器整体行为的设置，包括输出目录、作者信息、Kotlin 模式、Swagger 集成、时间类型策略等。
     * @param outputDir
     * @return
     */
    public static GlobalConfig findGlobalConfig(String outputDir){
        GlobalConfig globalConfig = new GlobalConfig.Builder()
                .disableOpenDir() // 允许自动打开输出目录
//                .outputDir("/path/to/output") // 设置输出目录
                .outputDir(outputDir)
                .author("Your Name") // 设置作者名
//                .enableSwagger() // 开启 Swagger 模式
//                .enableSpringdoc()
                .dateType(DateType.ONLY_DATE) // 设置时间类型策略
                .commentDate("yyyy-MM-dd hh:mm:ss") // 设置注释日期格式
                .build();
        return globalConfig;
    }

    /**
     * 数据源配置
     * @return
     */
    public static DataSourceConfig findDbConfig(){

        // 使用SQL查询的方式生成代码,属于旧的代码生成方式,通用性不是好,老的代码可以继续使用,适配数据库需要完成dbQuery和typeConvert的扩展,后期不再维护这种方式
        DataSourceConfig dataSourceConfig = new DataSourceConfig.Builder("jdbc:oracle:thin:@192.168.1.90:1521:orcl", "maige", "5sl84L0fVFxpVt")
//        DataSourceConfig dataSourceConfig = new DataSourceConfig.Builder("jdbc:oracle:thin:@192.168.1.18:1521:orcl", "maige", "5sl84L0fVFxpVt")
//        DataSourceConfig dataSourceConfig = new DataSourceConfig.Builder("jdbc:oracle:thin:@192.168.1.18:1521:orcl", "maige", "5sl84L0fVFxpVt")
//                .dbQuery(new MySqlQuery())
                .schema("MAIGE")
//                .typeConvert(new MySqlTypeConvert())
//                .keyWordsHandler(new MySqlKeyWordsHandler())
//                .databaseQueryClass(SQLQuery.class)
                .build();
        return dataSourceConfig;
    }

    /**
     * 包配置 (PackageConfig)
     * 包配置用于定义生成代码的包结构，包括父包名、模块名、实体类包名、服务层包名等
     * @return
     */
    public static PackageConfig findPackageConfig(String parentPackagePath,String moduleNamePath,String entityPath,String servicePath,
                                                  String serviceImplPath,String mapperPath,String xmlPather,String controllerPath,
                                                  String xmlFilePath){
        PackageConfig.Builder packageConfigBuilder = new PackageConfig.Builder()
                .parent(parentPackagePath) // 设置父包名
                .moduleName(moduleNamePath) // 设置父包模块名
                .entity(entityPath) // 设置 Entity 包名
//                .service(servicePath) // 设置 Service 包名
//                .serviceImpl(serviceImplPath) // 设置 Service Impl 包名
                .mapper(mapperPath) // 设置 Mapper 包名
                .xml(xmlPather) // 设置 Mapper XML 包名
//                .controller(controllerPath) // 设置 Controller 包名
                .pathInfo(Collections.singletonMap(OutputFile.xml, xmlFilePath)); // 设置路径配置信息

        if(StrUtil.isNotBlank(servicePath)){
            packageConfigBuilder.service(servicePath);
        }
        if(StrUtil.isNotBlank(serviceImplPath)){
            packageConfigBuilder.serviceImpl(serviceImplPath);
        }
        if(StrUtil.isNotBlank(controllerPath)){
            packageConfigBuilder.controller(controllerPath);
        }

        return packageConfigBuilder.build();
    }

    /**
     * 策略配置 (StrategyConfig)
     * 策略配置是 MyBatis-Plus 代码生成器的核心部分，它允许开发者根据项目需求定制代码生成的规则，包括命名模式、表和字段的过滤、以及各个代码模块的生成策略。
     * @return
     */
    public  static StrategyConfig findStrategyConfig(List<String> tablenameList){
        StrategyConfig.Builder strategyConfig = new StrategyConfig.Builder()
                .enableCapitalMode() // 开启大写命名
                .enableSkipView() // 开启跳过视图
                .disableSqlFilter() // 禁用 SQL 过滤
                .addInclude(tablenameList)
//                .likeTable(new LikeTable("USER")) // 模糊匹配表名
//                .addInclude("t_simple") // 增加表匹配
                .addTablePrefix("t_", "T_"); // 增加过滤表前缀
//                .addFieldSuffix("_flag") // 增加过滤字段后缀
        // 设置entity策略
        findEntityStrategyConfig(strategyConfig);
        // 设置mapper策略
        findMapperStrategy(strategyConfig);
        return strategyConfig.build();
    }

    /**
     * Entity 策略配置
     * 实体策略配置用于定制实体类的生成规则，包括父类、序列化版本 UID、文件覆盖、字段常量、链式模型、Lombok 模型等。
     * @return
     */
    public static void findEntityStrategyConfig(StrategyConfig.Builder builder){
        builder.entityBuilder()
//                .superClass(BaseEntity.class)
//                .disableSerialVersionUID()
//                .enableChainModel()
                .enableLombok()
                .enableRemoveIsPrefix()
                .enableTableFieldAnnotation()
                .enableActiveRecord()
//                .versionColumnName("version")
//                .logicDeleteColumnName("deleted")
                .naming(NamingStrategy.underline_to_camel)
//                .enableColumnConstant()
                .enableFileOverride()
                .columnNaming(NamingStrategy.underline_to_camel)
//                .addSuperEntityColumns("id", "created_by", "created_time", "updated_by", "updated_time")
//                .addIgnoreColumns("age")
//                .addTableFills(new Column("create_time", FieldFill.INSERT))
//                .addTableFills(new Property("updateTime", FieldFill.INSERT_UPDATE))
//                .idType(IdType.AUTO)
                .formatFileName("%s");
//        ;
    }

    /**
     * Controller 策略配置
     * Controller 策略配置用于定制 Controller 类的生成规则，包括父类、文件覆盖、驼峰转连字符、RestController 注解等。
     * @return
     */
    public static StrategyConfig findControllerStrategy(){
        StrategyConfig strategyConfig = new StrategyConfig.Builder()
                .controllerBuilder()
//                .superClass(BaseController.class)
                .enableHyphenStyle()
                .enableRestStyle()
                .formatFileName("%sAction")
                .build();
        return strategyConfig;
    }

    /**
     * Service 策略配置
     * Service 策略配置用于定制 Service 接口和实现类的生成规则，包括父类、文件覆盖、文件名称转换等。
     * @return
     */
    public static StrategyConfig findServiceStrategy(){
        StrategyConfig strategyConfig = new StrategyConfig.Builder()
                .serviceBuilder()
//                .superServiceClass(BaseService.class)
//                .superServiceImplClass(BaseServiceImpl.class)
                .formatServiceFileName("%sService")
                .formatServiceImplFileName("%sServiceImpl")
                .build();
        return strategyConfig;
    }
    /**
     * Mapper 策略配置
     * Mapper 策略配置用于定制 Mapper 接口和对应的 XML 映射文件的生成规则，包括父类、文件覆盖、Mapper 注解、结果映射、列列表、缓存实现类等。
     * @return
     */
    public static void findMapperStrategy(StrategyConfig.Builder builder){
        builder.mapperBuilder()
//                .superClass(BaseMapper.class)
                .enableMapperAnnotation()
                .enableBaseResultMap()
                .enableBaseColumnList()
//                .cache(MyMapperCache.class)
                .formatMapperFileName("%sMapper")
                .formatXmlFileName("%sMapper");
    }

}
